/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.testis.gui.mvc.view.labels;

import org.testis.orm.labelhandler.LabelRefined;
import org.testis.utils.tree.DefaultMutableLabelNode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;

/**
 *
 * @author selcuk
 */
public class LabelJTreeWithCheckbox extends JTree {

    public LabelJTreeWithCheckbox() {
        super();
        initLabelTree();
        refreshLabelTree(getLabelTreeModel(new ArrayList<Integer>()));
    }

    public LabelJTreeWithCheckbox(List<Integer> selectedLabels) {
        super();
        initLabelTree();
        refreshLabelTree(getLabelTreeModel(selectedLabels));
    }

    public void loadLabels(List<Integer> selectedLabels) {
        refreshLabelTree(getLabelTreeModel(selectedLabels));
    }

    /*
    public void loadLabels(List<LabelRefined> selectedLabels) {
        List<Integer> li = new ArrayList<Integer>();
        for (Iterator<LabelRefined> it = selectedLabels.iterator(); it.hasNext();) {
            li.add(it.next().getId());
        }
        loadLabels(li);
    }*/

    private void initLabelTree() {
        getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        putClientProperty("JTree.lineStyle", "Angled");
        setCellRenderer(new TwoStateLabelNodeRenderer());
        setCellEditor(new LabelTreeNodeEditor(this));
        setEditable(true);
        setExpandsSelectedPaths(false);
        setRootVisible(false);
    }

    private void refreshLabelTree(DefaultTreeModel model) {
        setModel(model);
        updateUI();
        expand();
    }

    private void expand() {
        for (int i = 0; i < getRowCount(); i++) {
            expandRow(i);
        }
    }

    private DefaultTreeModel getLabelTreeModel(List<Integer> selectedLabels) {
        ILabelTreeLoader treeLoader = new DefaultLabelTreeLoader();
        DefaultMutableLabelNode root = treeLoader.loadTree(selectedLabels);
        return new DefaultTreeModel(root);
    }

    public List<String> getSelectedLabelNames() {
        List<LabelRefined> selectedList = getSelectedLabels();
        List<String> result = new ArrayList<String>();
        for (Iterator<LabelRefined> it = selectedList.iterator(); it.hasNext();) {
            result.add(it.next().getName());
        }
        return result;
    }

    public List<LabelRefined> getSelectedLabels() {
        List<LabelRefined> result = new ArrayList<LabelRefined>();
        javax.swing.tree.TreeModel model = getModel();
        if (model != null) {
            Object root = model.getRoot();
            walkSelectedLabels(model, root, result);
        }
        return result;
    }

    private void walkSelectedLabels(javax.swing.tree.TreeModel model, Object o, List<LabelRefined> li) {
        DefaultMutableLabelNode node = (DefaultMutableLabelNode) o;
        LabelRefined label = node.getLabel();
        if (node.isSelected() && label != null) {
            li.add(label);
        }

        int cc = model.getChildCount(o);
        for (int i = 0; i < cc; i++) {
            Object child = model.getChild(o, i);
            walkSelectedLabels(model, child, li);
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                List<Integer> selectedList = new ArrayList<Integer>();
//                selectedList.add(7);
//                selectedList.add(11);
//                selectedList.add(12);
                LabelJTreeWithCheckbox tree = new LabelJTreeWithCheckbox();
                frame.getContentPane().add(tree);
                frame.pack();
                tree.loadLabels(selectedList);
                frame.setVisible(true);
            }
        });
    }
}
